#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <string.h>

/*
 * 多线程编程
 * 这个例子是两种进程同时修改一个变量的值
 */
#define MAX 10
pthread_t thread[2];
pthread_mutex_t mut;
int number = 0;

void *thread1(void* pv)
{
	printf("Thread1: I'm in thread1\n");
	printf("线程ID: %d\n", getpid());
	printf("线程组ID: %d\n", getpgid());
	printf("父线程ID: %d\n", getppid());
	int i = 0;
	for (i = 0; i < MAX; ++i)
	{
		pthread_mutex_lock(&mut);
		++number;
		pthread_mutex_unlock(&mut);
		printf("thread1: i = %d number = %d\n", i, number);
	}
	printf("thread1: 主函数在等我完成吗?\n");//如果没有打印这一句，说明主线程在当前线程结束前就退出了
	pthread_exit(NULL);
}

void *thread2(void *pv)
{
	printf("Thread2: I'm in thread2\n");
	int i = 0;
	for (i = 0; i < MAX; ++i)
	{
		pthread_mutex_lock(&mut);
		--number;
		pthread_mutex_unlock(&mut);
		printf("thread2: i = %d number = %d\n", i, number);
	}
	printf("thread2: 主函数在等我完成吗?\n");
	pthread_exit(NULL);

}

/*
 * 进程被创建时，系统会为其创建一个主线程，
 * 而要在进程中创建新的线程，则可以调用pthread_create
 * int pthread_create(
 *						pthread_t *thread, 
 *						const pthread_attr_t *attr,
 *						void *(*start_routine) (void *), 
 *						void *arg)
 * @param: start_routine为新线程的入口函数
 * @param: arg为传递给start_routine的参数。
 */
void thread_create(void)
{
	int temp;
	memset(&thread, 0, sizeof(thread));

	if ((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0)
	{
		printf("线程1创建失败!\n");
	}
	else
	{
		printf("线程1创建成功!\n");
	}

	if ((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0)
	{
		printf("线程2创建失败!\n");
	}
	else
	{
		printf("线程2创建成功!\n");
	}
}

/*
 * int pthread_join(
 *					pthread_t thread, 
 *					void **retval);
 * 代码中如果没有pthread_join主线程会很快结束从而使整个进程结束，
 * 从而使创建的线程没有机会开始执行就结束了。
 * 加入pthread_join后，主线程会一直等待直到等待的线程结束自己才结束，使创建的线程有机会执行。
 *
 * 注意，使用了phtread_join后，主线程会一直阻塞在pthread_join的调用处，直到此线程结束再继续运行。
 */
void thread_wait(void)
{
	if (thread[0]  != 0)
	{
		pthread_join(thread[0], NULL);
		printf("线程一已经结束...\n");
	}

	if (thread[1]  != 0)
	{
		pthread_join(thread[1], NULL);
		printf("线程二已经结束...\n");
	}
}

int main(void)
{
	/*用默认属性初始化互斥锁*/
	pthread_mutex_init(&mut,NULL);
	printf("主函数：创建线程。。。\n");
	thread_create();
	printf("主函数：等待线程结束。。。\n");
	thread_wait();
	return 0;
}

